package day26.yichang;

import java.io.*;

/**
 * throws和throw关键字示例
 * 演示throws关键字声明异常和throw关键字抛出异常
 * 
 * throws: 用于方法签名中声明该方法可能抛出的异常，告知调用者需要处理这些异常
 * throw: 用于方法体内主动抛出异常对象
 */
public class ThrowsThrowDemo {
    
    /**
     * 使用throws声明可能抛出的受检异常IOException
     * 当方法内可能产生受检异常(checked exception)时，必须使用throws声明或try-catch处理
     * @param fileName 要读取的文件名
     * @throws IOException 当文件不存在或读取文件出现问题时抛出
     */
    public static void readFile(String fileName) throws IOException {
        // 创建FileReader对象来读取文件
        FileReader file = new FileReader(fileName);
        // 创建BufferedReader来按行读取文件内容
        BufferedReader reader = new BufferedReader(file);
        // 读取文件第一行内容
        String line = reader.readLine();
        // 输出读取到的文件内容
        System.out.println("文件内容: " + line);
        // 关闭资源，释放文件句柄
        reader.close();
    }
    
    /**
     * 演示throw关键字抛出运行时异常
     * 运行时异常(RuntimeException)不需要在方法签名中声明
     * @param a 被除数
     * @param b 除数
     * @return 除法运算结果
     * @throws ArithmeticException 当除数为0时抛出算术异常
     */
    public static int divide(int a, int b) {
        // 判断除数是否为0，防止除零异常
        if (b == 0) {
            // 使用throw关键字主动抛出异常对象
            throw new ArithmeticException("除数不能为零");
        }
        // 执行除法运算并返回结果
        return a / b;
    }
    
    /**
     * 演示抛出受检异常
     * 受检异常必须在方法签名中使用throws声明或者使用try-catch捕获
     * @param age 年龄参数
     * @throws Exception 当年龄为负数或超过150时抛出一般异常
     */
    public static void checkAge(int age) throws Exception {
        // 检查年龄是否为负数
        if (age < 0) {
            // 抛出一般异常，包含错误信息
            throw new Exception("年龄不能为负数: " + age);
        }
        // 检查年龄是否超过150岁
        if (age > 150) {
            // 抛出一般异常，包含错误信息
            throw new Exception("年龄不能超过150: " + age);
        }
        // 年龄合法时输出提示信息
        System.out.println("年龄合法: " + age);
    }
    
    /**
     * 主方法，演示throws和throw的使用方式
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        System.out.println("=== throws和throw关键字示例 ===");
        
        // 演示处理受检异常(IOException)
        // readFile方法声明了throws IOException，所以调用时必须处理该异常
        try {
            readFile("test.txt");
        } catch (IOException e) {
            // 捕获并处理文件读取异常
            System.out.println("文件读取异常: " + e.getMessage());
        }
        
        // 演示throw抛出运行时异常(ArithmeticException)
        // 运行时异常不需要在方法签名中声明，但可以被捕获处理
        try {
            int result = divide(10, 0);
            System.out.println("除法结果: " + result);
        } catch (ArithmeticException e) {
            // 捕获并处理算术异常（除零异常）
            System.out.println("算术异常: " + e.getMessage());
        }
        
        // 演示处理throw抛出的受检异常(Exception)
        // checkAge方法声明了throws Exception，调用时必须处理
        try {
            checkAge(-5);
        } catch (Exception e) {
            // 捕获并处理年龄检查异常（负数年龄）
            System.out.println("检查年龄时发生异常: " + e.getMessage());
        }
        
        // 检查超过正常范围的年龄
        try {
            checkAge(200);
        } catch (Exception e) {
            // 捕获并处理年龄检查异常（年龄过大）
            System.out.println("检查年龄时发生异常: " + e.getMessage());
        }
        
        // 检查合法年龄
        try {
            checkAge(25);
        } catch (Exception e) {
            // 捕获并处理年龄检查异常（正常情况不会执行到这里）
            System.out.println("检查年龄时发生异常: " + e.getMessage());
        }
        
        // 程序正常执行完毕
        System.out.println("程序执行完毕");
    }
}